Blockly.FieldAngle.CLOCKWISE = true;
Blockly.FieldAngle.OFFSET = 90;

// 控制标志位
let isPaused = true;
let isStopped = false;


Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
Blockly.JavaScript.addReservedWords('highlightBlock');


function highlightBlock(id) {
    workspace.highlightBlock(id);
}

Blockly.Blocks['nav_goal'] = {
    init: function() {
        this.appendDummyInput()
            .appendField(new Blockly.FieldLabelSerializable("导航到目标点"), "nav-goal-text")
            .appendField(new Blockly.FieldDropdown(blocklyList), "goal-list")
            .appendField(new Blockly.FieldCheckbox("TRUE"), "is-wait-nav")
            .appendField(new Blockly.FieldLabelSerializable("等待导航完成"), "is-wait-nav-text");
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setColour(230);
    this.setTooltip("");
    this.setHelpUrl("");
    }
};

Blockly.Blocks['relative_move'] = {
    init: function() {
        this.appendDummyInput()
            .setAlign(Blockly.ALIGN_RIGHT)
            .appendField(new Blockly.FieldLabelSerializable("底盘相对移动"), "relative-move-text")
            .appendField(new Blockly.FieldLabelSerializable(" x:"), "relative-move-x-text")
            .appendField(new Blockly.FieldNumber(0, -100, 100), "relative-move-x")
            .appendField("cm;")
            .appendField(new Blockly.FieldLabelSerializable(" y:"), "relative-move-y-text")
            .appendField(new Blockly.FieldNumber(0, -100, 100), "relative-move-y")
            .appendField("cm;")
            .appendField(new Blockly.FieldLabelSerializable(" angle:"), "relative-move-angle-text")
            .appendField(new Blockly.FieldAngle(0), "relative-move-angle")
            .appendField("cm;");
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setColour(230);
    this.setTooltip("");
    this.setHelpUrl("");
  }
};

Blockly.Blocks['track'] = {
    init: function() {
        this.appendDummyInput()
            .appendField(new Blockly.FieldLabelSerializable("机器人对准AR码"), "track-text")
            .appendField(new Blockly.FieldNumber(0, 0, 100), "track-mark-id");
        this.appendStatementInput("track-next")
            .setCheck(null)
            .appendField(new Blockly.FieldLabelSerializable("成功"), "track-input-text");
        this.setInputsInline(false);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setColour(230);
    this.setTooltip("");
    this.setHelpUrl("");
    }
};
Blockly.Blocks['voice_collect'] = {
    init: function() {
      this.appendDummyInput()
          .appendField("麦克风音频采集");
      this.setOutput(true, "audio");
      this.setColour(230);
   this.setTooltip("采集一段音频");
   this.setHelpUrl("");
    }
  };
  
  Blockly.Blocks['voice_iat'] = {
    init: function() {
      this.appendValueInput("NAME")
          .setCheck("audio")
          .appendField("语音识别");
      this.setInputsInline(true);
      this.setOutput(true, "String");
      this.setColour(230);
   this.setTooltip("可以将音频内容，转为文本");
   this.setHelpUrl("");
    }
  };
Blockly.Blocks['voice_aiui'] = {
    init: function() {
        this.appendValueInput("NAME")
            .setCheck("String")
            .appendField("语音交互");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setColour(230);
    this.setTooltip("可以理解文本内容，并生成回答");
    this.setHelpUrl("");
    }
};
  
Blockly.Blocks['voice_tts'] = {
    init: function() {
        this.appendValueInput("NAME")
            .setCheck("String")
            .appendField("语音生成");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setColour(230);
    this.setTooltip("可以将字符串转换为音频并播放");
    this.setHelpUrl("");
    }
};

/*
机械臂控制块
*/
Blockly.Blocks['goto_position'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("手臂移动到点");
    this.appendValueInput("x")
        .setCheck("Number")
        .appendField("x:");
    this.appendValueInput("y")
        .setCheck("Number")
        .appendField("y:");
    this.appendValueInput("z")
        .setCheck("Number")
        .appendField("z:");
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(230);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};

Blockly.Blocks['get_markposition'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("获取ID为")
        .appendField(new Blockly.FieldNumber(0, 0, Infinity, 1), "id")
        .appendField("的ar码位姿列表");
    this.setInputsInline(false);
    this.setOutput(true, "Array");
    this.setColour(230);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};

Blockly.Blocks['set_pump'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("设置气泵状态")
        .appendField(new Blockly.FieldDropdown([["关闭","false"], ["开启","true"]]), "NAME");
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(230);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};

Blockly.Blocks['get_marklist'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("获取检测到二维码列表");
    this.setOutput(true, "Array");
    this.setColour(230);
 this.setTooltip("");
 this.setHelpUrl("");
  }
};


Blockly.Blocks['set_endservos'] = {
  init: function() {
    this.appendValueInput("NAME")
        .setCheck("Number")
        .appendField("控制机械手末端旋转:");
    this.appendDummyInput()
        .appendField("度");
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(230);
 this.setTooltip("设置机械手末端旋转角度，单位为角度");
 this.setHelpUrl("");
  }
};
javascript.javascriptGenerator.forBlock['nav_goal'] = function(block, generator) {
    var field_nav_goal_text = block.getFieldValue('nav-goal-text');
    var dropdown_goal_list = block.getFieldValue('goal-list');
    var checkbox_is_wait_nav = block.getFieldValue('is-wait-nav') === 'TRUE';
    var field_is_wait_nav_text = block.getFieldValue('is-wait-nav-text');
    // TODO: Assemble javascript into code variable.
    // var code = 'await RobotBase.goto_NavGoal(PoseList["'+dropdown_goal_list+'"])\n';
    var code = 'await RobotBase.goto_NavGoal(PoseList["'+dropdown_goal_list+'"]);\n';
    return code;
};

javascript.javascriptGenerator.forBlock['relative_move'] = function(block, generator) {
    var field_relative_move_text = block.getFieldValue('relative-move-text');
    var field_relative_move_x_text = block.getFieldValue('relative-move-x-text');
    var number_relative_move_x = block.getFieldValue('relative-move-x');
    var field_relative_move_y_text = block.getFieldValue('relative-move-y-text');
    var number_relative_move_y = block.getFieldValue('relative-move-y');
    var field_relative_move_angle_text = block.getFieldValue('relative-move-angle-text');
    var angle_relative_move_angle = block.getFieldValue('relative-move-angle');
    // TODO: Assemble javascript into code variable.
    // var code = 'await RobotBase.relative_move('+number_relative_move_x+','+number_relative_move_y+','+angle_relative_move_angle+')\n';
    var code = 'await RobotBase.relative_move('+number_relative_move_x+','+number_relative_move_y+','+angle_relative_move_angle+');\n';
    return code;
};

javascript.javascriptGenerator.forBlock['track'] = function(block, generator) {
    var field_track_text = block.getFieldValue('track-text');
    var number_track_mark_id = block.getFieldValue('track-mark-id');
    var field_track_input_text = block.getFieldValue('track-input-text');
    var statements_track_next = generator.statementToCode(block, 'track-next');
    // TODO: Assemble javascript into code variable.
    // var code = 'await RobotBase.goto_track('+number_track_mark_id+')\n'+statements_track_next;
    var code = 'await RobotBase.goto_track('+number_track_mark_id+');\n'+statements_track_next;
    return code;
};

// javascript.javascriptGenerator.forBlock['voice_detect'] = function(block, generator) {
//     // TODO: Assemble javascript into code variable.
//     var code = 'await RobotBase.voice_detect()\n';
//     // TODO: Change ORDER_NONE to the correct strength.
//     return [code, javascript.Order.NONE];
// };

javascript.javascriptGenerator.forBlock['voice_collect'] = function(block, generator) {
    // TODO: Assemble javascript into code variable.
    var code = `await RobotBase.voice_collect()`;
    // TODO: Change ORDER_NONE to the correct strength.
    return [code, javascript.Order.NONE];
};
  
// javascript.javascriptGenerator.forBlock['voice_iat'] = function(block, generator) {
//     var value_name = generator.valueToCode(block, 'NAME', javascript.Order.ATOMIC);
//     // TODO: Assemble javascript into code variable.
//     console.log(value_name);
//     var code = `await RobotBase.voice_iat(${value_name});`;
//     return code;
// };

javascript.javascriptGenerator.forBlock['voice_iat'] = function(block, generator) {
    var value_name = generator.valueToCode(block, 'NAME', javascript.Order.ATOMIC);
    // TODO: Assemble javascript into code variable.
    var code = `await RobotBase.voice_iat(${value_name})`;
    // TODO: Change ORDER_NONE to the correct strength.
    return [code, javascript.Order.NONE];
  };

javascript.javascriptGenerator.forBlock['voice_aiui'] = function(block, generator) {
    var value_name = generator.valueToCode(block, 'NAME', javascript.Order.ATOMIC);
    // TODO: Assemble javascript into code variable.
    var code = `var text = await RobotBase.voice_aiui(1,${value_name});\nawait RobotBase.voice_tts(text);\n`;
    return code;
  };

javascript.javascriptGenerator.forBlock['voice_tts'] = function(block, generator) {
    var value_name = generator.valueToCode(block, 'NAME', javascript.Order.ATOMIC);
    // TODO: Assemble javascript into code variable.
    var code = `await RobotBase.voice_tts(${value_name});\n`;
    return code;
};

javascript.javascriptGenerator.forBlock['goto_position'] = function(block, generator) {
  var value_x = generator.valueToCode(block, 'x', javascript.Order.ATOMIC);
  var value_y = generator.valueToCode(block, 'y', javascript.Order.ATOMIC);
  var value_z = generator.valueToCode(block, 'z', javascript.Order.ATOMIC);
  // TODO: Assemble javascript into code variable.
  var code = `await RobotBase.arm_move(${value_x},${value_y},${value_z});\n`;
  return code;
};

javascript.javascriptGenerator.forBlock['get_markposition'] = function(block, generator) {
  var number_id = block.getFieldValue('id');
  // TODO: Assemble javascript into code variable.
  var code = `await RobotBase.get_tf("robot","ar_marker_${number_id}")`;
  // TODO: Change ORDER_NONE to the correct strength.
  return [code, javascript.Order.NONE];
};

javascript.javascriptGenerator.forBlock['set_pump'] = function(block, generator) {
  var dropdown_name = block.getFieldValue('NAME');
  // TODO: Assemble javascript into code variable.
  var code = `await RobotBase.arm_setpump(${dropdown_name});\n`;
  return code;
};

javascript.javascriptGenerator.forBlock['get_marklist'] = function(block, generator) {
  // TODO: Assemble javascript into code variable.
  var code = 'await RobotBase.find_marklist()';
  // TODO: Change ORDER_NONE to the correct strength.
  return [code, javascript.Order.NONE];
};

javascript.javascriptGenerator.forBlock['set_endservos'] = function(block, generator) {
  var value_name = generator.valueToCode(block, 'NAME', javascript.Order.ATOMIC);
  // TODO: Assemble javascript into code variable.
  var code = '...\n';
  return code;
};

BlocklyStorage.backupOnUnload = function(opt_workspace) {
    var workspace = opt_workspace || Blockly.getMainWorkspace();
    window.addEventListener('unload',
        function() {
            BlocklyStorage.backupBlocks_(workspace);
    }, false);
};

/**
 * Restore code blocks from localStorage.
 * @param {Blockly.WorkspaceSvg=} opt_workspace Workspace. 
 */
BlocklyStorage.restoreBlocks = function(opt_workspace) {
    var url = window.location.href.split('#')[0];
    if ('localStorage' in window && window.localStorage[url]) {
        var workspace = opt_workspace || Blockly.getMainWorkspace();
        var xml = Blockly.utils.xml.textToDom(window.localStorage[url]);
        Blockly.Xml.domToWorkspace(xml, workspace);
    }
};

var robot_run = document.getElementById('robot-run');
var robot_stop = document.getElementById('robot-stop');

robot_run.onclick = function() {
    if(ros_is_linked){
        isPaused = false
        if (isStopped){
            rei_log('继续运行');
        }else{
            generateJsCode();
        }
        isStopped = false
    }else{
        alert('程序未启动')
    }
}

robot_stop.onclick = function() {
    if(isPaused==false){
        if (isStopped) {
            if (window.confirm("是否终止任务？")){
                isPaused = true;
                isStopped = false;
            }
        }else{
            isStopped = true;
            rei_log('暂停运行');
        }
    }else{
        alert('没有在运行的程序')
    }
}
// 运行脚本的函数
function generateJsCode() {
    // 生成 JavaScript 代码
    var code = Blockly.JavaScript.workspaceToCode(workspace);
    console.log(code)
    // 插入控制逻辑
    // runcode = `
    //     async function innerRun() {
    //         rei_log('开始执行任务');
    //         while (isStopped) { await new Promise(r => setTimeout(r, 100));}
    //         var RobotBase = new robot_api.RobotBase({ros:ros});
    //         ${code.replace(/(.*)/g, 'while (isStopped) { await new Promise(r => setTimeout(r, 100)); }\nif (isPaused) { \nhighlightBlock("");\nrei_log("终止运行");\nreturn true; }\n$1')}
    //         highlightBlock("");
    //         rei_log('任务执行结束');
    //     }
    //     innerRun();
    // `;
    runcode = `
        async function innerRun() {
            rei_log('开始执行任务');
            while (isStopped) { await new Promise(r => setTimeout(r, 100));}
            var RobotBase = new robot_api.RobotBase({ros:ros});
            ${code.replace(/(.*)/g, 'while (isStopped) { await new Promise(r => setTimeout(r, 100)); }\nif (isPaused) { \nhighlightBlock("");\nrei_log("终止运行");\nreturn true; }\n$1')}
            highlightBlock("");
            rei_log('任务执行结束');
        }
        innerRun();
    `;
    // 执行生成的代码
    try {
        eval(runcode)
        // new Function('highlightBlock', 'isPaused', 'isStopped', runcode)(highlightBlock, isPaused, isStopped);
    } catch (error) {
        console.error('脚本执行出错:', error);
    }
}

